package org.cybzacg.convert.converters.gather;

import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.enums.ConversionError;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;
import org.cybzacg.convert.exception.ConversionException;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 通用集合类型转换器
 * 支持各种集合类型之间的转换（作为其他集合转换器的后备）
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "CollectionConverter", priority = ConversionPriority.MEDIUM, description = "集合类型转换器，支持各种集合类型之间的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Collection.class }, tags = { "collection", "container", "conversion" })
public class CollectionConverter extends AbstractCollectionConverter<Collection<Object>> {

    // 集合类型实现类映射
    private static final Map<Class<?>, Class<?>> COLLECTION_IMPLEMENTATIONS = new ConcurrentHashMap<>();

    static {
        COLLECTION_IMPLEMENTATIONS.put(Collection.class, ArrayList.class);
        COLLECTION_IMPLEMENTATIONS.put(List.class, ArrayList.class);
        COLLECTION_IMPLEMENTATIONS.put(Set.class, HashSet.class);
        COLLECTION_IMPLEMENTATIONS.put(SortedSet.class, TreeSet.class);
        COLLECTION_IMPLEMENTATIONS.put(NavigableSet.class, TreeSet.class);
        COLLECTION_IMPLEMENTATIONS.put(Queue.class, LinkedList.class);
        COLLECTION_IMPLEMENTATIONS.put(Deque.class, ArrayDeque.class);
    }

    public CollectionConverter() {
        super(Collection.class, ConversionPriority.MEDIUM);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.COLLECTION;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> Collection<Object> createEmptyCollection(Class<T> targetType) {
        try {
            // 如果是具体的Collection实现类，直接实例化
            if (Collection.class.isAssignableFrom(targetType) &&
                    !targetType.isInterface() &&
                    !java.lang.reflect.Modifier.isAbstract(targetType.getModifiers())) {
                return (Collection<Object>) targetType.getDeclaredConstructor().newInstance();
            }

            // 根据接口类型选择实现类
            Class<?> implementationClass = COLLECTION_IMPLEMENTATIONS.get(targetType);
            if (implementationClass != null) {
                return (Collection<Object>) implementationClass.getDeclaredConstructor().newInstance();
            }

            // 根据目标类型特征选择合适的实现
            if (Set.class.isAssignableFrom(targetType)) {
                return new HashSet<>();
            } else if (Queue.class.isAssignableFrom(targetType)) {
                return new LinkedList<>();
            } else if (Deque.class.isAssignableFrom(targetType)) {
                return new ArrayDeque<>();
            }

            // 默认使用ArrayList
            return new ArrayList<>();

        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "无法创建Collection实例: " + targetType.getSimpleName(), e);
        }
    }

    @Override
    protected String getDefaultMapConversionMode() {
        return "entries"; // Collection默认转换Map的entries
    }

    @Override
    public String getName() {
        return "CollectionConverter";
    }

    // ========== 静态工具方法 ==========

    /**
     * 检查是否为Collection类型
     */
    public static boolean isCollectionType(Class<?> clazz) {
        return Collection.class.isAssignableFrom(clazz);
    }

    /**
     * 创建ArrayList的便捷方法
     */
    public static ArrayList<Object> toArrayList(Object source) {
        CollectionConverter converter = new CollectionConverter();
        try {
            return (ArrayList<Object>) converter.convertToCollection(source, ArrayList.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为ArrayList失败: " + source, e);
        }
    }

    /**
     * 创建HashSet的便捷方法
     */
    public static HashSet<Object> toHashSet(Object source) {
        CollectionConverter converter = new CollectionConverter();
        try {
            return (HashSet<Object>) converter.convertToCollection(source, HashSet.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为HashSet失败: " + source, e);
        }
    }

    /**
     * 检查Collection是否为空或null
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 获取Collection的安全大小
     */
    public static int safeSize(Collection<?> collection) {
        return collection != null ? collection.size() : 0;
    }
}
